﻿using DataMgr.File;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using DataMgr.mode;

namespace DataMgr.Export
{
    class BdfDataTransfer
    {
        public static string[] RecordLayerTitles = { "记录序号", "记录时间", "电压(V)", "电流(A)", "温度", "容量(Ah)", "绝对时间", "功率(W)", "工步时间", "能量", "内阻" };
        public static string[] CycleLayerTitles = { "循环序号", "充电容量(Ah)", "放电容量(Ah)", "充电时间", "放电时间", "中值电压(V)", "充电能量", "放电能量" };
        public static string[] StepLayerTitles = { "工步序号", "工步类型", "工步时间", "终止容量(Ah)", "起始电压(V)", "终止电压(V)", "起始温度", "终止温度", "充电中值电压(V)", "放电中值电压(V)", "原工步号", "能量" };
        public static string[] LogTitles = { "日志序号", "记录序号", "时间", "事件", "备注" };
        public static readonly string[] g_Ware0 = {("母线过压"), ("母线欠压"), ("电池继电器开路故障"),("电池过压"),("电池欠压"),("电池过流"),("电池未接入"),("模块过热")};
        public static readonly string[] g_Ware1 = {("软启动失败"), ("模块并机通讯故障"), ("邻机故障"), ("辅助电源故障"),("风扇故障"),("继电器短路故障"),("继电器开路故障"),("电池继电器短路故障")};
        public static readonly string[] g_Ware2 = {("系统通讯故障"), ("启动失败"), ("初始化失败"),("紧急停机"),("模块配置错误"),("母线过流"),("功率线反接"),("功率线断路")};
        public static readonly string[] g_Ware3 = {("模块三相电流不平衡"), ("自定义工作模式配置失败"), ("电压线反接"),("输入端口过压"),("输入端口欠压"),("通道异常"),("地址拨码错误"),("变压器过温")};
        public static readonly string[] g_Ware4 = {("单体过压"), ("单体欠压"), ("过温保护"),("低温保护"),("---"),("---"),("---"),("---")};
        public static readonly string[] g_Ware7 = {("---"), ("---"), ("---"),("---"),("---"),("---"),("---"),("通道状态告警")};
        public static string[] AdvStepTitles = { "工步号", "工步名称", "参数名", "参数值", "截止条件", "运算符", "运算值", "与或", "动作", "记录条件", "记录值", "延时保护" };
        public static string[] StdStepTitles = { "工步号", "工步名称", "电压(V)", "电流(A)", "时间", "截止电流(A)", "截止电压(V)", "容量(Ah)", "功率(W)", "延时(ms)" };

        public static List<string> FormatRecordLayer(BdfRecord pRecord)
        {
            List<string> rdStr = new List<string>();
            rdStr.Add((pRecord.GetRecordID()).ToString());
            rdStr.Add(FromatTimeSpan(pRecord.GetTime(), true));
            rdStr.Add((pRecord.GetVol()).ToString("F3"));
            rdStr.Add((pRecord.GetCur()).ToString("F3"));
            rdStr.Add((pRecord.GetTemp()).ToString("F3"));
            rdStr.Add((pRecord.GetCap()).ToString("F3"));
            rdStr.Add(FromatAbsTime(pRecord.GetLocalTime()));
            rdStr.Add((pRecord.GetPow()).ToString("F3"));
            rdStr.Add(FromatTimeSpan(pRecord.GetTimeOffStep(), true));
            rdStr.Add((pRecord.GetEng()).ToString("F3"));
            rdStr.Add((pRecord.GetIR()).ToString("F3"));
            return rdStr;
        }
        public static List<string> FormatCycleLayer(CycleStatisticsNode cycle)
        {
            //{ "循环序号", "充电容量", "放电容量", "充电时间", "放电时间", "中值电压", "充电能量", "放电能量" };
            List<string> cycleStr = new List<string>();
            cycleStr.Add((cycle.dwCycleIndex + 1).ToString());
            //cycleStr.Add((cycle.dCrgCap* DaFileElement.SCALE_CN).ToString("F3"));
            //cycleStr.Add((cycle.dDcrgCap * DaFileElement.SCALE_CN).ToString("F3"));
            cycleStr.Add((cycle.dCrgCap).ToString("F3"));
            cycleStr.Add((cycle.dDcrgCap).ToString("F3"));
            cycleStr.Add(FromatTimeSpan(cycle.ullChargeTime));
            cycleStr.Add(FromatTimeSpan(cycle.ullDischargeTime));
            //cycleStr.Add((cycle.dMedianVoltage * DaFileElement.SCALE_IU).ToString("F3"));
            //cycleStr.Add((cycle.dCrgEng * DaFileElement.SCALE_CN).ToString("F3"));
            //cycleStr.Add((cycle.dDcrgEng * DaFileElement.SCALE_CN).ToString("F3"));
            cycleStr.Add((cycle.dMedianVoltage).ToString("F3"));
            cycleStr.Add((cycle.dCrgEng).ToString("F3"));
            cycleStr.Add((cycle.dDcrgEng).ToString("F3"));
            return cycleStr;
        }

        public static List<string> FormatStepLayer(StepStatisticsNode stepNode)
        {
            List<string> stepStr = new List<string>();
            stepStr.Add((1 + stepNode.dwStepIndex).ToString());
            stepStr.Add(GetStepTypeName(stepNode.btStepType));
            stepStr.Add(FromatTimeSpan(stepNode.nTimeSection));
            stepStr.Add((stepNode.dCap).ToString("F3"));
            stepStr.Add((stepNode.dVolStart).ToString("F3"));
            stepStr.Add((stepNode.dVolEnd).ToString("F3"));
            stepStr.Add((stepNode.dTempStart).ToString("F1"));
            stepStr.Add((stepNode.dTempEnd).ToString("F1"));
            stepStr.Add((stepNode.dCrgMidVol).ToString("F3"));
            stepStr.Add((stepNode.dDcrgMidVol).ToString("F3"));
            stepStr.Add((stepNode.stepID).ToString());
            stepStr.Add((stepNode.dEng).ToString("F3"));

            return stepStr;
        }

        public static List<string> FormatLog(SingleHisLogData log)
        {
            List<string> logRecord = new List<string>();
            logRecord.Add(log.nRecordSeq.ToString());
            logRecord.Add(log.nRefTestSn.ToString());
            logRecord.Add(FromatAbsTime(log.dTestTime));
            logRecord.Add(GetLogEvent(log.nEvent));
            logRecord.Add(GetLogEventValue(log.nEvent,(UInt64)log.nEventValue));

            return logRecord;
        }
        public static string GetLogEvent(int nEvent)
        {
            string name = "";
            switch (nEvent)
            {
                case 1:
                    name = "完成";
                    break;
                case 2:
                    name = "启动";
                    break;
                case 3:
                    name = "暂停";
                    break;
                case 4:
                    name = "接续";
                    break;
                case 5:
                    name = "停止";
                    break;
                case 6:
                    name = "跳转";
                    break;
                case 7:
                    name = "断电";
                    break;
                case 8:
                    name = "上电";
                    break;
                case 9:
                    name = "中位机磁盘满";
                    break;
                case 10:
                    name = "工步转换";
                    break;
                case 11:
                    name = "工步保护";
                    break;
                case 12:
                    name = "工步结束";
                    break;
                case 13:
                    name = "工步跳转";
                    break;
                default:
                    break;
            }

            return name;
        }
        public static string GetLogEventValue(int nEvent, UInt64 nEventValue)
        {
            string str = "";
            if (0xFFFE == nEventValue)
            {
                str = "电压突变截止";
            }
            else if (0xFFFF == nEventValue)
            {
                str = "工步执行完毕";
            }
            else if (10 <= nEvent && 13 >= nEvent)//工步转换,工步保护
            {
                str = GetCondName((int)nEventValue);
            }
            else if (3 == nEvent)   //暂停
            {
                if (0 == nEventValue)
                    str = "手动暂停";
                else if (1 == nEventValue)
                    str = "系统告警";
                else if (2 == nEventValue)
                    str = "截止保护";
                else if (3 == nEventValue)
                    str = "掉电保护";
            }
            else if (20 == nEvent)  //DC告警
            {
                str = GetWarnInfo(nEventValue);
            }
            else
            {
                str = nEventValue.ToString();
            }

            return str;
        }
        public static string FromatTimeSpan(UInt64 ms, bool bWithMs = false)
        {
            TimeSpan sum = new TimeSpan(0, 0, 0, 0, (int)ms);

            string strHour = sum.Hours.ToString("D2");// Fill(sum.Hours.ToString(), '0', 2, 'L');
            string strMin = sum.Minutes.ToString("D2");//Fill(sum.Minutes.ToString(), '0', 2, 'L');
            string strSen = sum.Seconds.ToString("D2");//Fill(sum.Seconds.ToString(), '0', 2, 'L');
            string sSumTime = strHour + ":" + strMin + ":" + strSen;
            if (bWithMs)
                sSumTime += ":" + sum.Milliseconds.ToString("D3");

            return sSumTime;

        }

        public static string FromatAbsTime(double ms)
        {
            System.DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime(new System.DateTime(1970, 1, 1)); // 当地时区
            DateTime dt = startTime.AddMilliseconds(ms);
            return dt.ToString();
        }

        public static string GetStepTypeName(int mode)
        {
            if (false)
            {
                switch ((StepType)mode)
                {
                    case StepType.STEP_MODE_IDLE:
                        return "Rest";
                    case StepType.STEP_MODE_I_CHARGE:
                        return "CC_Chg";
                    case StepType.STEP_MODE_U_CHARGE:
                        return "CV_Chg";
                    case StepType.STEP_MODE_POWER_CHARGE:
                        return "CP_Chg";
                    case StepType.STEP_MODE_IU_CHARGE:
                        return "CCCV_Chg";
                    case StepType.STEP_MODE_I_UNCHARGE:
                        return "CC_DChg";
                    case StepType.STEP_MODE_U_UNCHARGE:
                        return "CV_DChg";
                    case StepType.STEP_MODE_POWER_UNCHARGE:
                        return "CP_DChg";
                    case StepType.STEP_MODE_IU_UNCHARGE:
                        return "CCCV_DChg";
                    case StepType.STEP_MODE_IR_DCHARGE:
                        return "CR_DChg";
                    case StepType.STEP_MODE_IR_CHARGE:
                        return "CR_Chg";
                    case StepType.STEP_MODE_PULSE:
                        return "Pulse";
                    case StepType.STEP_MODE_HILL:
                        return "Hill";
                    case StepType.STEP_MODE_SIM_CHARGE:
                        return "SIM";
                    case StepType.STEP_MODE_Li_CHARGE:
                        return "DCIR";
                    case StepType.STEP_MODE_RECYCLE:
                        return "Cycle";
                    case StepType.STEP_MODE_FINISH:
                        return "End";
                }

                return "undefine";
            }
            else
            {
                switch ((StepType)mode)
                {
                    case StepType.STEP_MODE_IDLE:
                        return "静置";
                    case StepType.STEP_MODE_I_CHARGE:
                        return "恒流充电";
                    case StepType.STEP_MODE_U_CHARGE:
                        return "恒压充电";
                    case StepType.STEP_MODE_POWER_CHARGE:
                        return "恒功率充电";
                    case StepType.STEP_MODE_IU_CHARGE:
                        return "恒流恒压充电";
                    case StepType.STEP_MODE_I_UNCHARGE:
                        return "恒流放电";
                    case StepType.STEP_MODE_U_UNCHARGE:
                        return "恒压放电";
                    case StepType.STEP_MODE_POWER_UNCHARGE:
                        return "恒功率放电";
                    case StepType.STEP_MODE_IU_UNCHARGE:
                        return "恒流恒压放电";
                    case StepType.STEP_MODE_IR_DCHARGE:
                        return "恒阻放电";
                    case StepType.STEP_MODE_IR_CHARGE:
                        return "恒阻充电";
                    case StepType.STEP_MODE_PULSE:
                        return "脉冲";
                    case StepType.STEP_MODE_HILL:
                        return "斜坡";
                    case StepType.STEP_MODE_SIM_CHARGE:
                        return "模拟工况";
                    case StepType.STEP_MODE_Li_CHARGE:
                        return "直流内阻测试";
                    case StepType.STEP_MODE_RECYCLE:
                        return "循环";
                    case StepType.STEP_MODE_FINISH:
                        return "结束";
                }

                return "未定义";
            }
            //public static List<string> GetCycleLayerTitles()
            //{

            //}
        }

        public static string GetCondName(int condType)
        {
            string name = "";
            switch ((COND_PARA)condType)
            {
                case COND_PARA.COND_PARA_TIME:
                    name = "时间";
                    break;
                case COND_PARA.COND_PARA_VOL:
                    name = "电压";
                    break;
                case COND_PARA.COND_PARA_CUR:
                    name = "电流";
                    break;
                case COND_PARA.COND_PARA_CAP:
                    name = "容量";
                    break;
                case COND_PARA.COND_PARA_NRG:
                    name = "能量";
                    break;
                case COND_PARA.COND_PARA_TEMP:
                    name = "温度";
                    break;
                case COND_PARA.COND_PARA_CHG_CAP:
                    name = "充电容量";
                    break;
                case COND_PARA.COND_PARA_DISCHG_CAP:
                    name = "放电容量";
                    break;
                case COND_PARA.COND_PARA_CHG_NRG:
                    name = "充电能量";
                    break;
                case COND_PARA.COND_PARA_DISCHG_NRG:
                    name = "放电能量";
                    break;
                case COND_PARA.COND_SINGLE_VOL:
                    name = "单体总电压";
                    break;
                case COND_PARA.COND_SINGLE_MAXVOL:
                    name = "单体电压最大值";
                    break;
                case COND_PARA.COND_SINGLE_MINVOL:
                    name = "单体电压最小值";
                    break;
                case COND_PARA.COND_SINGLE_ERRVOL:
                    name = "单体电压差";
                    break;
                case COND_PARA.COND_SINGLE_MAXTEMP:
                    name = "单体温度最大值";
                    break;
                case COND_PARA.COND_SINGLE_MINTEMP:
                    name = "单体温度最小值";
                    break;
                case COND_PARA.COND_SINGLE_ERRTEMP:
                    name = "单体温度差";
                    break;
                case COND_PARA.COND_SINGLE_SOC:
                    name = "SOC";
                    break;
                case COND_PARA.COND_SINGLE_CUR:
                    name = "总电流";
                    break;
                default:
                    break;
            }

            return name;
        }

        public static string GetWarnInfo(UInt64 llWarn)
        {
            UInt16 wWarn0, wWarn1, wWarn2, wWarn3, wWarn4, wWarn7;
            wWarn0 = (UInt16)(llWarn & 0xFF);
            wWarn1 = (UInt16)((llWarn & 0xFF00) >> 8);

            wWarn2 = (UInt16)((llWarn & 0xFF0000) >> 16);

            wWarn3 = (UInt16)((llWarn & 0xFF000000) >> 24);

            wWarn4 = (UInt16)((llWarn & 0xFF00000000) >> 32);
            wWarn7 = (UInt16)((llWarn & 0xFF00000000000000) >> 56);
            string strWarnMsg = "";
            string SEP_FLAG = ";";
            for (int i = 0; i < 8; i++)
            {
                if (((UInt16)Math.Pow(2.0, i) & wWarn0) > 0)
                {
                    strWarnMsg += g_Ware0[i];
                    strWarnMsg += SEP_FLAG;
                }
            }

            for (int i = 0; i < 8; i++)
            {
                if (((UInt16)Math.Pow(2.0, i) & wWarn1) > 0)
                {
                    strWarnMsg += g_Ware1[i];
                    strWarnMsg += SEP_FLAG;
                }
            }

            for (int i = 0; i < 8; i++)
            {
                if (((UInt16)Math.Pow(2.0, i) & wWarn2) > 0)
                {
                    strWarnMsg += g_Ware2[i];
                    strWarnMsg += SEP_FLAG;
                }
            }

            for (int i = 0; i < 8; i++)
            {
                if (((UInt16)Math.Pow(2.0, i) & wWarn3) > 0)
                {
                    strWarnMsg += g_Ware3[i];
                    strWarnMsg += SEP_FLAG;
                }
            }

            for (int i = 0; i < 8; i++)
            {
                if (((UInt16)Math.Pow(2.0, i) & wWarn4) > 0)
                {
                    strWarnMsg += g_Ware4[i];
                    strWarnMsg += SEP_FLAG;
                }
            }
            for (int i = 0; i < 8; i++)
            {
                if (((UInt16)Math.Pow(2.0, i) & wWarn7) > 0)
                {
                    strWarnMsg += g_Ware7[i];
                    strWarnMsg += SEP_FLAG;
                }
            }
            return strWarnMsg;
        }

        //旧工步信息转换到新的
        public static void TransStepInfo(StepFileInfo sInfo1, ref BmsStepFileInfo stepInfo)
        {
            stepInfo.szMark = sInfo1.szMark;
            stepInfo.uProtectState = sInfo1.uProtectState;
            stepInfo.highVol = sInfo1.highVol;
            stepInfo.lowVol = sInfo1.lowVol;
            stepInfo.highCurrent = sInfo1.highCurrent;
            stepInfo.lowCurrent = sInfo1.lowCurrent;
            stepInfo.highPower = sInfo1.highPower;
            stepInfo.lowPower = sInfo1.lowPower;
            stepInfo.highCap = sInfo1.highCap;
            stepInfo.lowCap = sInfo1.lowCap;
            stepInfo.highTemp = sInfo1.highTemp;
            stepInfo.lowTemp = sInfo1.lowTemp;
            stepInfo.uRecordState = sInfo1.uRecordState;
            stepInfo.timeInterval = sInfo1.timeInterval;
            stepInfo.volInterval = sInfo1.volInterval;
            stepInfo.curInterval = sInfo1.curInterval;
            stepInfo.platVol1 = sInfo1.platVol1;
            stepInfo.platVol2 = sInfo1.platVol2;
            stepInfo.platVol3 = sInfo1.platVol3;
            stepInfo.platErr = sInfo1.platErr;
        }
        //旧截止条件转换到新的
        public static void TransStepCond(StopCond sCond, ref CutOffCondition cond)
        {
            cond.CutOffConditionType = sCond.endCond;
            cond.CutOffConditionRaletion = sCond.relation;
            cond.CutOffConditionParam = sCond.endCondValue;
            cond.CutOffConditionParamCondition = sCond.endCondOp;
            cond.CutOffConditionProcessingType = sCond.action;
        }

        //获取截止类型名称
        public static string GetStepCondName(int condType)
        {
            string name = "";
            switch ((COND_PARA)condType)
            {
                case COND_PARA.COND_PARA_TIME:
                    name = "时间";
                    break;
                case COND_PARA.COND_PARA_VOL:
                    name = "电压";
                    break;
                case COND_PARA.COND_PARA_CUR:
                    name = "电流";
                    break;
                case COND_PARA.COND_PARA_CAP:
                    name = "容量";
                    break;
                case COND_PARA.COND_PARA_NRG:
                    name = "能量";
                    break;
                case COND_PARA.COND_PARA_TEMP:
                    name = "温度";
                    break;
                case COND_PARA.COND_PARA_CHG_CAP:
                    name = "充电容量";
                    break;
                case COND_PARA.COND_PARA_DISCHG_CAP:
                    name = "放电容量";
                    break;
                case COND_PARA.COND_PARA_CHG_NRG:
                    name = "充电能量";
                    break;
                case COND_PARA.COND_PARA_DISCHG_NRG:
                    name = "放电能量";
                    break;
                case COND_PARA.COND_SINGLE_VOL:
                    name = "单体总电压";
                    break;
                case COND_PARA.COND_SINGLE_MAXVOL:
                    name = "单体电压最大值";
                    break;
                case COND_PARA.COND_SINGLE_MINVOL:
                    name = "单体电压最小值";
                    break;
                case COND_PARA.COND_SINGLE_ERRVOL:
                    name = "单体电压差";
                    break;
                case COND_PARA.COND_SINGLE_MAXTEMP:
                    name = "单体温度最大值";
                    break;
                case COND_PARA.COND_SINGLE_MINTEMP:
                    name = "单体温度最小值";
                    break;
                case COND_PARA.COND_SINGLE_ERRTEMP:
                    name = "单体温度差";
                    break;
                case COND_PARA.COND_SINGLE_SOC:
                    name = "SOC";
                    break;
                case COND_PARA.COND_SINGLE_CUR:
                    name = "总电流";
                    break;
                default:
                    break;
            }
            return name;
        }

        public static string GetStepCondOper(byte oper)
        {
            string name = "";
            switch (oper)
            {
                case 1:
                    name = ">";
                    break;
                case 2:
                    name = ">=";
                    break;
                case 3:
                    name = "<=";
                    break;
                case 4:
                    name = "=";
                    break;
                case 5:
                    name = "!=";
                    break;
            }

            return name;
        }

        public static string GetStepCondRelation(byte relation)
        {
            string name = "";
            if (1 == relation)
                name = "或";
            else if (2 == relation)
                name = "与";
            else if (3 == relation)
                name = "与子项";
            return name;
        }

        public static string GetStepCondAction(byte action)
        {
            string name = "";
            if (1 == action)
                name = "下一工步";
            else if (2 == action)
                name = "结束";
            else if (3 == action)
                name = "保护";
            return name;
        }

        public static string GetRecordName(byte recordType)
        {
            string name = "";
            if (1 == recordType)
                name = "ΔT";
            else if (2 == recordType)
                name = "ΔV";
            else if (3 == recordType)
                name = "ΔI";
            return name;
        }
    }
}
